﻿using BCCommon;
using BCCommon.OAEnums.WorkflowActive;
using BCCommon.TMS.Agent;
using BCData.OA.WorkflowTemplate.WorkflowTemplateStepFormTemplateConfig;
using BCData.TMS.Agent.AgentRecord;
using BCData.TMS.PlatformManageFee.PlatformManageFeeConfig;
using BCDto.OA.WorkflowActive.WorkflowActivity;
using BCDto.OA.WorkflowActive.WorkflowActivityOperation;
using BCDto.OA.WorkflowActive.WorkflowActivityStep;
using BCDto.OA.WorkflowActive.WorkflowActivityStepFormConfig;
using BCDto.OA.WorkflowActive.WorkflowActivityStepSpecificFormItem;
using BCDto.Sim.Admin.Admin;
using BCDto.TMS.Agent.AgentBusiness;
using BCDto.TMS.Agent.AgentCurrentlyProtocol;
using BCDto.TMS.Agent.AgentCurrentlyProtocolAttachment;
using BCDto.TMS.Agent.AgentRecord;
using BCDto.Utils;
using BCEntity.OA.WorkflowTemplate.WorkflowTemplateStepFormTemplateConfig;
using BCService.OA.WorkflowActivity;
using BCService.OA.WorkflowTemplate.WorkflowTemplate;
using BCService.Sim.Agent.Agent;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace BCService.TMS.Agent.Agent
{
    public class AgentBusinessService : IAgentBusinessService
    {
        public readonly IDatabaseContext databaseContext;
        public readonly IWorkflowActivityService workflowActivityService;
        public readonly IWorkflowTemplateService workflowTemplateService;
        public readonly IWorkflowTemplateStepFormTemplateConfigData workflowTemplateStepFormTemplateConfigData;
        private readonly IAgentRecordData agentRecordData;
        private readonly IPlatformManageFeeConfigData platformManageFeeConfigData;
        public AgentBusinessService(IDatabaseContext databaseContext,
            IWorkflowActivityService workflowActivityService,
            IWorkflowTemplateService workflowTemplateService,
            IWorkflowTemplateStepFormTemplateConfigData workflowTemplateStepFormTemplateConfigData,
            IAgentRecordData agentRecordData,
            IPlatformManageFeeConfigData platformManageFeeConfigData)
        {
            this.databaseContext = databaseContext;
            this.workflowActivityService = workflowActivityService;
            this.workflowTemplateService = workflowTemplateService;
            this.workflowTemplateStepFormTemplateConfigData = workflowTemplateStepFormTemplateConfigData;
            this.agentRecordData = agentRecordData;
            this.platformManageFeeConfigData = platformManageFeeConfigData;
        }

        public WorkflowActivityDto ApplicationOpenChildAgent(AdminDto adminDto, AgentBusinessRequestDto requestDto)
        {
            var workflowTempalteDto = this.workflowTemplateService.GetBySpecificKey(requestDto.SpecificTemplateKey);

            #region 代理商申请开通检查

            #endregion



            databaseContext.BeginTransaction();
            var workflowActivityDto = this.workflowActivityService.InitActivity(workflowTempalteDto.WorkflowTemplateId, adminDto, null);
            var workflowActivityStepDto = this.workflowActivityService.GetActivityStepList(workflowActivityDto.WorkflowActivityId).Single(p => p.Step == 0);
            var stepFormTemplateConfigEntities = this.workflowTemplateStepFormTemplateConfigData.GetStepFormList(workflowActivityStepDto.TemplateStepCode).GetAwaiter().GetResult();

            List<WorkflowActivityStepFormConfigRequestDto> workflowActivityStepFormConfigList = new List<WorkflowActivityStepFormConfigRequestDto>();
            workflowActivityStepFormConfigList.Add(SetStepFormConfig(adminDto.CompanyId == 1 ? TMSSubmitRoleType.HeadOffice : TMSSubmitRoleType.Agent, requestDto, workflowActivityDto, workflowActivityStepDto, stepFormTemplateConfigEntities.First()));

            List<WorkflowActivityStepFormConfigDto> formConfigResult = this.workflowActivityService.SubmitForm(workflowActivityStepFormConfigList, adminDto, null);

            WorkflowActivityStepDto stepDto = this.workflowActivityService.UpdateStepStatusToActivity(new WorkflowActivityStepPutDto()
            {
                WorkflowActivityStepId = workflowActivityStepDto.WorkflowActivityStepId
            }, adminDto, null);

            var result = this.workflowActivityService.Execution(new WorkflowActivityOperationRequestDto()
            {
                StepCompleteType = OAActivityStepCompleteType.Pass,
                WorkflowActivityId = workflowActivityDto.WorkflowActivityId,
                WorkflowActivityStepId = workflowActivityStepDto.WorkflowActivityStepId
            });
            databaseContext.Commit();
            return result;
        }

        private WorkflowActivityStepFormConfigRequestDto SetStepFormConfig(TMSSubmitRoleType submitRole, AgentBusinessRequestDto agentBusinessRequestDto, WorkflowActivityDto workflowActivityDto, WorkflowActivityStepDto workflowActivityStepDto, WorkflowTemplateStepFormTemplateConfigEntity workflowTemplateStepFormTemplateConfigEntity)
        {
            WorkflowActivityStepFormConfigRequestDto requestDto = new WorkflowActivityStepFormConfigRequestDto();
            requestDto.WorkflowActivityId = workflowActivityDto.WorkflowActivityId;
            requestDto.Step = workflowActivityStepDto.Step;
            requestDto.FormConfigTitle = workflowTemplateStepFormTemplateConfigEntity.FormConfigTitle;
            requestDto.FormConfigCode = workflowTemplateStepFormTemplateConfigEntity.FormConfigCode;
            requestDto.SpecificFormName = workflowTemplateStepFormTemplateConfigEntity.FormConfigTitle;
            requestDto.IsSpecificForm = true;

            List<WorkflowActivityStepSpecificFormItemRequestDto> itemsRequestList = new List<WorkflowActivityStepSpecificFormItemRequestDto>();

            SetAdminFormItems(agentBusinessRequestDto.Admin, requestDto, itemsRequestList, submitRole, null, null);
            SetCompanyFormItems(agentBusinessRequestDto.Company, requestDto, itemsRequestList, submitRole, null, null);
            SetAgentFormItems(agentBusinessRequestDto.Agent, requestDto, itemsRequestList, submitRole, 1, null);
            SetAgentAreaManageFeeFormItems(agentBusinessRequestDto.AgentAreaList, requestDto, itemsRequestList, submitRole, 1, null);
            SetAgentProtocolFormItems(agentBusinessRequestDto.AgentProtocolList, requestDto, itemsRequestList, submitRole, 1, 1);

            requestDto.SpecificFormItemActivity = itemsRequestList;
            return requestDto;
        }

        private void SetAdminFormItems(AgentAdminInfoRequestDto adminInfo, WorkflowActivityStepFormConfigRequestDto requestDto, List<WorkflowActivityStepSpecificFormItemRequestDto> itemsRequestList,
            TMSSubmitRoleType submitRole, int? formConfigRows, int? formItemRows)
        {

            Type type = adminInfo.GetType();
            PropertyInfo[] properties = type.GetProperties();
            foreach (PropertyInfo property in properties)
            {
                Attribute attribute = property.GetCustomAttribute(typeof(DisplayAttribute));
                NonInjectionAttribute nonInjectionAttribute = property.GetCustomAttribute<NonInjectionAttribute>();
                if (nonInjectionAttribute == null)
                {
                    if (attribute != null)
                    {
                        WorkflowFormItemShowNameAttribute showNameAttribute = property.GetCustomAttribute<WorkflowFormItemShowNameAttribute>();
                        FileTypeAttribute fileTypeAttribute = property.GetCustomAttribute<FileTypeAttribute>();
                        string suffix = "input";
                        if (fileTypeAttribute != null)
                        {
                            suffix = fileTypeAttribute.Suffix(property.GetValue(adminInfo)?.ToString());
                        }
                        if (showNameAttribute != null)
                        {
                            PropertyInfo propertyInfo = properties.Single(p => p.Name.Equals(showNameAttribute.LinkName));
                            string showName = propertyInfo.GetValue(adminInfo)?.ToString();
                            DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                            itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "Admin", property.Name, displayAttribute.Name,
                                property.GetValue(adminInfo)?.ToString(), showName, suffix, 1, false, submitRole, formConfigRows, formItemRows, "Admin"));
                        }
                        else
                        {
                            string showName = string.Empty;
                            if (property.PropertyType.IsEnum)
                            {
                                showName = GetEnumDescription(property.GetValue(adminInfo));
                            }
                            DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                            itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "Admin", property.Name, displayAttribute.Name,
                                property.GetValue(adminInfo)?.ToString(), showName, suffix, 1, false, submitRole, formConfigRows, formItemRows, "Admin"));
                        }
                    }
                }
            }

        }
        private void SetCompanyFormItems(AgentCompanyInfoRequestDto companyInfo, WorkflowActivityStepFormConfigRequestDto requestDto, List<WorkflowActivityStepSpecificFormItemRequestDto> itemsRequestList,
            TMSSubmitRoleType submitRole, int? formConfigRows, int? formItemRows)
        {

            Type type = companyInfo.GetType();
            PropertyInfo[] properties = type.GetProperties();
            foreach (PropertyInfo property in properties)
            {
                Attribute attribute = property.GetCustomAttribute(typeof(DisplayAttribute));
                NonInjectionAttribute nonInjectionAttribute = property.GetCustomAttribute<NonInjectionAttribute>();
                if (nonInjectionAttribute == null)
                {
                    if (attribute != null)
                    {
                        WorkflowFormItemShowNameAttribute showNameAttribute = property.GetCustomAttribute<WorkflowFormItemShowNameAttribute>();
                        FileTypeAttribute fileTypeAttribute = property.GetCustomAttribute<FileTypeAttribute>();
                        string suffix = "input";
                        if (fileTypeAttribute != null)
                        {
                            suffix = fileTypeAttribute.Suffix(property.GetValue(companyInfo)?.ToString());
                        }
                        if (showNameAttribute != null)
                        {
                            PropertyInfo propertyInfo = properties.Single(p => p.Name.Equals(showNameAttribute.LinkName));
                            string showName = propertyInfo.GetValue(companyInfo)?.ToString();
                            string itemValue = property.GetValue(companyInfo)?.ToString();
                            DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                            if (property.PropertyType == typeof(DateTime))
                            {
                                itemValue = property.GetValue(companyInfo)?.ToDateTime().ToString("yyyy-MM-dd HH:mm:ss");
                            }
                            itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "Company", property.Name, displayAttribute.Name,
                                itemValue, showName, suffix, 1, false, submitRole, formConfigRows, formItemRows, "Company"));
                        }
                        else
                        {
                            string showName = string.Empty;
                            string itemValue = property.GetValue(companyInfo)?.ToString();
                            if (property.PropertyType.IsEnum)
                            {
                                showName = GetEnumDescription(property.GetValue(companyInfo));
                            }
                            if (property.PropertyType == typeof(DateTime))
                            {
                                itemValue = property.GetValue(companyInfo)?.ToDateTime().ToString("yyyy-MM-dd HH:mm:ss");
                            }
                            DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                            itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "Company", property.Name, displayAttribute.Name,
                                itemValue, showName, suffix, 1, false, submitRole, formConfigRows, formItemRows, "Company"));
                        }
                    }
                }
            }

        }
        private void SetAgentFormItems(AgentRecordRequestDto agentInfo, WorkflowActivityStepFormConfigRequestDto requestDto, List<WorkflowActivityStepSpecificFormItemRequestDto> itemsRequestList,
            TMSSubmitRoleType submitRole, int? formConfigRows, int? formItemRows)
        {

            Type type = agentInfo.GetType();
            PropertyInfo[] properties = type.GetProperties();
            foreach (PropertyInfo property in properties)
            {
                Attribute attribute = property.GetCustomAttribute(typeof(DisplayAttribute));
                NonInjectionAttribute nonInjectionAttribute = property.GetCustomAttribute<NonInjectionAttribute>();
                if (nonInjectionAttribute == null)
                {
                    if (attribute != null)
                    {
                        WorkflowFormItemShowNameAttribute showNameAttribute = property.GetCustomAttribute<WorkflowFormItemShowNameAttribute>();
                        FileTypeAttribute fileTypeAttribute = property.GetCustomAttribute<FileTypeAttribute>();
                        string suffix = "input";
                        if (fileTypeAttribute != null)
                        {
                            suffix = fileTypeAttribute.Suffix(property.GetValue(agentInfo)?.ToString());
                        }
                        if (showNameAttribute != null)
                        {
                            PropertyInfo propertyInfo = properties.Single(p => p.Name.Equals(showNameAttribute.LinkName));
                            string showName = propertyInfo.GetValue(agentInfo)?.ToString();
                            DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                            itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "AgentRecord", property.Name, displayAttribute.Name,
                                property.GetValue(agentInfo)?.ToString(), showName, suffix, 1, false, submitRole, formConfigRows, formItemRows, "AgentRecord"));
                        }
                        else
                        {
                            string showName = string.Empty;
                            if (property.PropertyType.IsEnum)
                            {
                                showName = GetEnumDescription(property.GetValue(agentInfo));
                            }
                            DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                            itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "AgentRecord", property.Name, displayAttribute.Name,
                                property.GetValue(agentInfo)?.ToString(), showName, suffix, 1, false, submitRole, formConfigRows, formItemRows, "AgentRecord"));
                        }
                    }
                }
            }

        }
        private void SetAgentAreaManageFeeFormItems(List<AgentAreaManageFeeViewRequestDto> agentAreaManageFeeInfoList, WorkflowActivityStepFormConfigRequestDto requestDto, List<WorkflowActivityStepSpecificFormItemRequestDto> itemsRequestList,
            TMSSubmitRoleType submitRole, int? formConfigRows, int? formItemRows)
        {
            int configRows = formConfigRows.HasValue ? formConfigRows.Value : 0;
            int itemRows = formItemRows.HasValue ? formItemRows.Value : 0;
            foreach (var agentAreaManageFeeInfo in agentAreaManageFeeInfoList)
            {
                Type type = agentAreaManageFeeInfo.GetType();
                PropertyInfo[] properties = type.GetProperties();
                foreach (PropertyInfo property in properties)
                {
                    Attribute attribute = property.GetCustomAttribute(typeof(DisplayAttribute));
                    NonInjectionAttribute nonInjectionAttribute = property.GetCustomAttribute<NonInjectionAttribute>();
                    if (nonInjectionAttribute == null)
                    {
                        if (attribute != null)
                        {
                            WorkflowFormItemShowNameAttribute showNameAttribute = property.GetCustomAttribute<WorkflowFormItemShowNameAttribute>();
                            FileTypeAttribute fileTypeAttribute = property.GetCustomAttribute<FileTypeAttribute>();
                            string suffix = "input";
                            if (fileTypeAttribute != null)
                            {
                                suffix = fileTypeAttribute.Suffix(property.GetValue(agentAreaManageFeeInfo)?.ToString());
                            }
                            if (showNameAttribute != null)
                            {
                                PropertyInfo propertyInfo = properties.Single(p => p.Name.Equals(showNameAttribute.LinkName));
                                string showName = propertyInfo.GetValue(agentAreaManageFeeInfo)?.ToString();
                                DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                                if (property.Name.IndexOf("Id") > -1 || property.Name.IndexOf("Code") > -1)
                                {
                                    itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "AgentAreaRecord", property.Name, displayAttribute.Name,
                                        property.GetValue(agentAreaManageFeeInfo)?.ToString(), showName, suffix, 1, false, submitRole, configRows, itemRows, "AgentAreaRecord"));
                                }
                                else
                                {
                                    itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "PlatformManageFeeConfig", property.Name, displayAttribute.Name,
                                        property.GetValue(agentAreaManageFeeInfo)?.ToString(), showName, suffix, 1, false, submitRole, configRows, itemRows, "PlatformManageFeeConfig"));
                                }
                                itemRows++;
                            }
                            else
                            {
                                string showName = string.Empty;
                                if (property.PropertyType.IsEnum)
                                {
                                    showName = GetEnumDescription(property.GetValue(agentAreaManageFeeInfo));
                                }
                                DisplayAttribute displayAttribute = attribute as DisplayAttribute;

                                if (property.Name.IndexOf("Id") > -1 || property.Name.IndexOf("Code") > -1)
                                {
                                    itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "AgentAreaRecord", property.Name, displayAttribute.Name,
                                        property.GetValue(agentAreaManageFeeInfo)?.ToString(), showName, "input", 1, false, submitRole, configRows, itemRows, "AgentAreaRecord"));
                                }
                                else
                                {
                                    itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "PlatformManageFeeConfig", property.Name, displayAttribute.Name,
                                        property.GetValue(agentAreaManageFeeInfo)?.ToString(), showName, "input", 1, false, submitRole, configRows, itemRows, "PlatformManageFeeConfig"));
                                }
                                itemRows++;
                            }
                        }
                    }
                }
                configRows++;
            }
        }


        private void SetAgentProtocolFormItems(List<AgentCurrentlyProtocolRequestDto> agentProtocolList, WorkflowActivityStepFormConfigRequestDto requestDto, List<WorkflowActivityStepSpecificFormItemRequestDto> itemsRequestList,
           TMSSubmitRoleType submitRole, int? formConfigRows, int? formItemRows)
        {
            int configRows = formConfigRows.HasValue ? formConfigRows.Value : 0;
            int itemRows = formItemRows.HasValue ? formItemRows.Value : 0;
            foreach (var protocol in agentProtocolList)
            {
                Type type = protocol.GetType();
                PropertyInfo[] properties = type.GetProperties();
                foreach (PropertyInfo property in properties)
                {
                    Attribute attribute = property.GetCustomAttribute(typeof(DisplayAttribute));
                    NonInjectionAttribute nonInjectionAttribute = property.GetCustomAttribute<NonInjectionAttribute>();
                    if (nonInjectionAttribute == null)
                    {
                        if (attribute != null && !property.PropertyType.IsGenericType)
                        {
                            WorkflowFormItemShowNameAttribute showNameAttribute = property.GetCustomAttribute<WorkflowFormItemShowNameAttribute>();
                            FileTypeAttribute fileTypeAttribute = property.GetCustomAttribute<FileTypeAttribute>();
                            string suffix = "input";
                            if (fileTypeAttribute != null)
                            {
                                suffix = fileTypeAttribute.Suffix(property.GetValue(protocol)?.ToString());
                            }
                            if (showNameAttribute != null)
                            {
                                PropertyInfo propertyInfo = properties.Single(p => p.Name.Equals(showNameAttribute.LinkName));
                                string showName = propertyInfo.GetValue(protocol)?.ToString();
                                string itemValue = property.GetValue(protocol)?.ToString();
                                DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                                if (property.PropertyType == typeof(DateTime))
                                {
                                    itemValue = property.GetValue(protocol)?.ToDateTime().ToString("yyyy-MM-dd HH:mm:ss");
                                }
                                itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "AgentCurrentlyProtocol", property.Name, displayAttribute.Name,
                                    itemValue, showName, suffix, 1, false, submitRole, configRows, itemRows, "AgentCurrentlyProtocol"));
                                itemRows++;
                            }
                            else
                            {
                                string showName = string.Empty;
                                string itemValue = property.GetValue(protocol)?.ToString();
                                if (property.PropertyType.IsEnum)
                                {
                                    showName = GetEnumDescription(property.GetValue(protocol));
                                }
                                if (property.PropertyType == typeof(DateTime))
                                {
                                    itemValue = property.GetValue(protocol)?.ToDateTime().ToString("yyyy-MM-dd HH:mm:ss");
                                }
                                DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                                itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "AgentCurrentlyProtocol", property.Name, displayAttribute.Name,
                                    itemValue, showName, suffix, 1, false, submitRole, formConfigRows, itemRows, "AgentCurrentlyProtocol"));
                                itemRows++;
                            }
                        }

                    }
                }
                SetAgentProtocolAttachmentsFormItems(protocol.AgentCurrentlyProtocolAttachments, requestDto, itemsRequestList, submitRole, configRows, formItemRows);
                configRows++;
            }
        }

        private void SetAgentProtocolAttachmentsFormItems(List<AgentCurrentlyProtocolAttachmentRequestDto> agentProtocolAttachmentList, WorkflowActivityStepFormConfigRequestDto requestDto, List<WorkflowActivityStepSpecificFormItemRequestDto> itemsRequestList,
           TMSSubmitRoleType submitRole, int? formConfigRows, int? formItemRows)
        {
            int itemRows = 0;
            foreach (var item in agentProtocolAttachmentList)
            {
                Type type = item.GetType();
                PropertyInfo[] properties = type.GetProperties();
                foreach (PropertyInfo property in properties)
                {
                    Attribute attribute = property.GetCustomAttribute(typeof(DisplayAttribute));
                    NonInjectionAttribute nonInjectionAttribute = property.GetCustomAttribute<NonInjectionAttribute>();
                    if (nonInjectionAttribute == null)
                    {
                        if (attribute != null && !property.PropertyType.IsGenericType)
                        {
                            WorkflowFormItemShowNameAttribute showNameAttribute = property.GetCustomAttribute<WorkflowFormItemShowNameAttribute>();
                            FileTypeAttribute fileTypeAttribute = property.GetCustomAttribute<FileTypeAttribute>();
                            string suffix = "input";
                            if (fileTypeAttribute != null)
                            {
                                suffix = fileTypeAttribute.Suffix(property.GetValue(item)?.ToString());
                            }
                            if (showNameAttribute != null)
                            {
                                PropertyInfo propertyInfo = properties.Single(p => p.Name.Equals(showNameAttribute.LinkName));
                                string showName = propertyInfo.GetValue(item)?.ToString();
                                DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                                itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "AgentCurrentlyProtocolAttachment", property.Name, displayAttribute.Name,
                                    property.GetValue(item)?.ToString(), showName, suffix, 1, false, submitRole, formConfigRows, itemRows, "AgentCurrentlyProtocolAttachment"));
                            }
                            else
                            {
                                string showName = string.Empty;
                                if (property.PropertyType.IsEnum)
                                {
                                    showName = GetEnumDescription(property.GetValue(item));
                                }
                                DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                                itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "AgentCurrentlyProtocolAttachment", property.Name, displayAttribute.Name,
                                    property.GetValue(item)?.ToString(), showName, suffix, 1, false, submitRole, formConfigRows, itemRows, "AgentCurrentlyProtocolAttachment"));
                            }
                        }
                    }
                }
                itemRows++;
            }
        }

        private string GetEnumDescription(object value)
        {
            DescriptionAttribute descriptionAttribute = value.GetType().GetTypeInfo().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault() as DescriptionAttribute;

            if (descriptionAttribute != null)
            {
                return descriptionAttribute.Description.IndexOf('|') != -1 ? descriptionAttribute.Description.Split('|')[1] : descriptionAttribute.Description;
            }

            return value.ToString();
        }

        #region 构建表单项
        /// <summary>
        /// 构建表单项
        /// </summary>
        /// <param name="formConfigTitle">步骤表单配置请求信息</param>
        /// <param name="formConfigCode">表单</param>
        /// <param name="table">绑定数据表</param>
        /// <param name="field">绑定数据字段</param>
        /// <param name="title">表单项标题</param>
        /// <param name="value">表单项值</param>
        /// <param name="itemShow">表单项显示值</param>
        /// <param name="itemType">表单项值的类型</param>
        /// <param name="itemWidth">0.5/1</param>
        /// <param name="isTitle">是否为表单标题</param>
        /// <param name="submitRole">提交人角色</param>
        /// <param name="formConfigRows">表单行号（用来确定一张表多行的数据编组用）</param>
        /// <param name="formItemRows">表单项行号（用来确定一张表一行的数据编组用）</param>
        /// <param name="formGroupName">前端不同表存储信息分组名称</param>
        /// <returns></returns>
        private WorkflowActivityStepSpecificFormItemRequestDto MakeFormItem(string formConfigTitle, string formConfigCode, string table, string field, string title,
            string value, string itemShow, string itemType, decimal itemWidth, bool isTitle, TMSSubmitRoleType submitRole, int? formConfigRows, int? formItemRows, string formGroupName)
        {
            WorkflowActivityStepSpecificFormItemRequestDto adminFormItem = new WorkflowActivityStepSpecificFormItemRequestDto();
            adminFormItem.FormConfigTitle = formConfigTitle;
            adminFormItem.FormConfigCode = formConfigCode;
            adminFormItem.FormItemCode = Guid.NewGuid().ToString();
            adminFormItem.FormDatabase = databaseContext.Master.Database;
            adminFormItem.FormTable = table;
            adminFormItem.BoundField = field;
            adminFormItem.ItemTitle = title;
            adminFormItem.ItemValue = value;
            adminFormItem.ItemShow = itemShow;
            adminFormItem.ItemType = itemType;
            adminFormItem.ItemWidth = itemWidth > 0.5M ? 1 : 0.5M;
            adminFormItem.IsFormTitle = isTitle;
            adminFormItem.SubmitRole = submitRole;
            if (!string.IsNullOrWhiteSpace(formGroupName))
            {
                adminFormItem.FormGroupName = formGroupName;
            }
            if (formConfigRows.HasValue)
            {
                adminFormItem.FormConfigRows = formConfigRows.Value;
            }
            if (formItemRows.HasValue)
            {
                adminFormItem.FormItemRows = formItemRows.Value;
            }
            return adminFormItem;
        }
        #endregion

        public WorkflowActivityDto ApplicationModifWyAgentInfo(AdminDto admin, AgentBusinessModifyDto modifyDto)
        {
            var workflowTempalteDto = this.workflowTemplateService.GetBySpecificKey(modifyDto.SpecificTemplateKey);
            long agentRecordId = 0;
            if (modifyDto.Agent != null) agentRecordId = modifyDto.Agent.AgentRecordId;
            else if (modifyDto.AgentAreaManageFee != null)
            {
                var platformManageFeeConfig = platformManageFeeConfigData.GetEntity(modifyDto.AgentAreaManageFee.PlatformManageFeeConfigId).Result;
                if (platformManageFeeConfig == null)
                {
                    throw new ArgumentException("平台管理费配置信息不存在");
                }
                agentRecordId = platformManageFeeConfig.SubAgentRecordId;
            }
            var agentRecord = this.agentRecordData.GetEntity(agentRecordId).Result;
            if (agentRecord == null)
            {
                throw new ArgumentException("代理商信息不存在");
            }

            databaseContext.BeginTransaction();
            var workflowActivityDto = this.workflowActivityService.InitActivity(workflowTempalteDto.WorkflowTemplateId, admin, null);
            var workflowActivityStepDto = this.workflowActivityService.GetActivityStepList(workflowActivityDto.WorkflowActivityId).Single(p => p.Step == 0);
            var stepFormTemplateConfigEntities = this.workflowTemplateStepFormTemplateConfigData.GetStepFormList(workflowActivityStepDto.TemplateStepCode).GetAwaiter().GetResult();

            List<WorkflowActivityStepFormConfigRequestDto> workflowActivityStepFormConfigList = new List<WorkflowActivityStepFormConfigRequestDto>();
            workflowActivityStepFormConfigList.Add(SetStepFormConfig(admin.CompanyId == 1 ? TMSSubmitRoleType.HeadOffice : TMSSubmitRoleType.Agent, modifyDto, workflowActivityDto, workflowActivityStepDto, stepFormTemplateConfigEntities.First()));

            List<WorkflowActivityStepFormConfigDto> formConfigResult = this.workflowActivityService.SubmitForm(workflowActivityStepFormConfigList, admin, null);

            WorkflowActivityStepDto stepDto = this.workflowActivityService.UpdateStepStatusToActivity(new WorkflowActivityStepPutDto()
            {
                WorkflowActivityStepId = workflowActivityStepDto.WorkflowActivityStepId
            }, admin, null);

            var result = this.workflowActivityService.Execution(new WorkflowActivityOperationRequestDto()
            {
                StepCompleteType = OAActivityStepCompleteType.Pass,
                WorkflowActivityId = workflowActivityDto.WorkflowActivityId,
                WorkflowActivityStepId = workflowActivityStepDto.WorkflowActivityStepId
            });
            databaseContext.Commit();
            return result;
        }

        private WorkflowActivityStepFormConfigRequestDto SetStepFormConfig(TMSSubmitRoleType submitRole, AgentBusinessModifyDto modifyDto, WorkflowActivityDto workflowActivityDto, WorkflowActivityStepDto workflowActivityStepDto, WorkflowTemplateStepFormTemplateConfigEntity workflowTemplateStepFormTemplateConfigEntity)
        {
            WorkflowActivityStepFormConfigRequestDto requestDto = new WorkflowActivityStepFormConfigRequestDto();
            requestDto.WorkflowActivityId = workflowActivityDto.WorkflowActivityId;
            requestDto.Step = workflowActivityStepDto.Step;
            requestDto.FormConfigTitle = workflowTemplateStepFormTemplateConfigEntity.FormConfigTitle;
            requestDto.FormConfigCode = workflowTemplateStepFormTemplateConfigEntity.FormConfigCode;
            requestDto.SpecificFormName = workflowTemplateStepFormTemplateConfigEntity.FormConfigTitle;
            requestDto.IsSpecificForm = true;

            List<WorkflowActivityStepSpecificFormItemRequestDto> itemsRequestList = new List<WorkflowActivityStepSpecificFormItemRequestDto>();
            if (modifyDto.Agent != null)
                SetModifyAgentFormItems(modifyDto.Agent, requestDto, itemsRequestList, submitRole, 1, null);
            if (modifyDto.AgentAreaManageFee != null)
                SetModifyAgentAreaManageFeeFormItems(modifyDto.AgentAreaManageFee, requestDto, itemsRequestList, submitRole, 1, null);
            if (modifyDto.AgentProtocolList != null && modifyDto.AgentProtocolList.Any())
                SetAgentProtocolFormItems(modifyDto.AgentProtocolList, requestDto, itemsRequestList, submitRole, 1, 1);

            requestDto.SpecificFormItemActivity = itemsRequestList;
            return requestDto;
        }

        private void SetModifyAgentAreaManageFeeFormItems(AgentAreaManageFeePutDto agentAreaManageFee, WorkflowActivityStepFormConfigRequestDto requestDto, List<WorkflowActivityStepSpecificFormItemRequestDto> itemsRequestList, TMSSubmitRoleType submitRole, int? formConfigRows, int? formItemRows)
        {
            int configRows = formConfigRows.HasValue ? formConfigRows.Value : 0;
            int itemRows = formItemRows.HasValue ? formItemRows.Value : 0;
            Type type = agentAreaManageFee.GetType();
            PropertyInfo[] properties = type.GetProperties();
            foreach (PropertyInfo property in properties)
            {
                Attribute attribute = property.GetCustomAttribute(typeof(DisplayAttribute));
                NonInjectionAttribute nonInjectionAttribute = property.GetCustomAttribute<NonInjectionAttribute>();
                if (nonInjectionAttribute == null)
                {
                    if (attribute != null)
                    {
                        WorkflowFormItemShowNameAttribute showNameAttribute = property.GetCustomAttribute<WorkflowFormItemShowNameAttribute>();
                        FileTypeAttribute fileTypeAttribute = property.GetCustomAttribute<FileTypeAttribute>();
                        string suffix = "input";
                        if (fileTypeAttribute != null)
                        {
                            suffix = fileTypeAttribute.Suffix(property.GetValue(agentAreaManageFee)?.ToString());
                        }
                        if (showNameAttribute != null)
                        {
                            PropertyInfo propertyInfo = properties.Single(p => p.Name.Equals(showNameAttribute.LinkName));
                            string showName = propertyInfo.GetValue(agentAreaManageFee)?.ToString();
                            DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                            itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "PlatformManageFeeConfig", property.Name, displayAttribute.Name,
                                property.GetValue(agentAreaManageFee)?.ToString(), showName, suffix, 1, false, submitRole, configRows, itemRows, "PlatformManageFeeConfig"));
                        }
                        else
                        {
                            string showName = string.Empty;
                            if (property.PropertyType.IsEnum)
                            {
                                showName = GetEnumDescription(property.GetValue(agentAreaManageFee));
                            }
                            DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                            itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "PlatformManageFeeConfig", property.Name, displayAttribute.Name,
                                property.GetValue(agentAreaManageFee)?.ToString(), showName, "input", 1, false, submitRole, configRows, itemRows, "PlatformManageFeeConfig"));
                        }
                    }
                }
            }
            configRows++;
        }

        private void SetModifyAgentFormItems(AgentRecordPutDto agentInfo, WorkflowActivityStepFormConfigRequestDto requestDto, List<WorkflowActivityStepSpecificFormItemRequestDto> itemsRequestList, TMSSubmitRoleType submitRole, int? formConfigRows, int? formItemRows)
        {
            Type type = agentInfo.GetType();
            PropertyInfo[] properties = type.GetProperties();
            foreach (PropertyInfo property in properties)
            {
                Attribute attribute = property.GetCustomAttribute(typeof(DisplayAttribute));
                NonInjectionAttribute nonInjectionAttribute = property.GetCustomAttribute<NonInjectionAttribute>();
                if (nonInjectionAttribute == null)
                {
                    if (attribute != null)
                    {
                        WorkflowFormItemShowNameAttribute showNameAttribute = property.GetCustomAttribute<WorkflowFormItemShowNameAttribute>();
                        FileTypeAttribute fileTypeAttribute = property.GetCustomAttribute<FileTypeAttribute>();
                        string suffix = "input";
                        if (fileTypeAttribute != null)
                        {
                            suffix = fileTypeAttribute.Suffix(property.GetValue(agentInfo)?.ToString());
                        }
                        if (showNameAttribute != null)
                        {
                            PropertyInfo propertyInfo = properties.Single(p => p.Name.Equals(showNameAttribute.LinkName));
                            string showName = propertyInfo.GetValue(agentInfo)?.ToString();
                            DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                            itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "AgentRecord", property.Name, displayAttribute.Name,
                                property.GetValue(agentInfo)?.ToString(), showName, suffix, 1, false, submitRole, formConfigRows, formItemRows, "AgentRecord"));
                        }
                        else
                        {
                            string showName = string.Empty;
                            if (property.PropertyType.IsEnum)
                            {
                                showName = GetEnumDescription(property.GetValue(agentInfo));
                            }
                            DisplayAttribute displayAttribute = attribute as DisplayAttribute;
                            itemsRequestList.Add(MakeFormItem(requestDto.FormConfigTitle, requestDto.FormConfigCode, "AgentRecord", property.Name, displayAttribute.Name,
                                property.GetValue(agentInfo)?.ToString(), showName, suffix, 1, false, submitRole, formConfigRows, formItemRows, "AgentRecord"));
                        }
                    }
                }
            }
        }
    }
}
